﻿using Helper;
using HtmlAgilityPack;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Drawing;
using System.Threading;
using System.Text.RegularExpressions;

namespace ConsoleApp.ZhiHu.HeadPicture
{
    class Program
    {
        /// <summary>
        /// 知乎问题前缀
        /// </summary>
        private static readonly string Url = "https://www.zhihu.com/question/";

        /// <summary>
        /// 每次能抓取最大数量 
        /// <!--已测试20为最大-->
        /// </summary>
        private static readonly decimal Limit = 20;

        private static readonly int JobsBirth = 19550224;
        static void Main(string[] args)
        {

            var number = string.Empty;
            var answerCount = default(HtmlNode);


            while (true)
            {
                Console.WriteLine("请输入知乎问题编号：");
                number = Console.ReadLine();

                if (string.IsNullOrEmpty(number))
                {
                    continue;
                }
                try
                {
                    var num = Convert.ToInt32(number);
                    if (num > JobsBirth && num < int.MaxValue)
                    {
                        var web = new HtmlWeb();
                        web.PreRequest += HtmlPreRequest;

                        var doc = web.Load(Url + number);

                        var flag = doc.DocumentNode.SelectSingleNode("//div[@class='ErrorPage']");
                        if (flag != null)
                        {
                            Console.WriteLine("问题编号未找到;");
                        }
                        else
                        {
                            answerCount = doc.DocumentNode.SelectSingleNode("//meta[@itemprop='answerCount']");
                            break;
                        }
                    }
                    else
                    {
                        Console.WriteLine("问题编号格式不正确");
                    }
                }
                catch (FormatException)
                {
                    Console.WriteLine("问题编号格式不正确");
                }
            }



            if (answerCount != null)
            {
                var count = answerCount.GetAttributeValue("content", 0);
                if (count != 0)
                {
                    Console.WriteLine($"共{count}条数据");
                    Console.WriteLine("开始抓取头像");
                    decimal t = 0;
                    for (int i = 0; i < Math.Ceiling(count / Limit); i++)
                    {
                        var str = Http(GetUrl(number, t));
                        var listImg = GetImgStr(str);

                        SaveImgs(listImg, t, number);
                        t += Limit;
                        Thread.Sleep(2000);
                    }
                }
            }

            Console.WriteLine("结束抓取头像");
        }

        private static void SaveImgs(List<string> imgs, decimal t, string questionNum)
        {
            var root = $"{AppDomain.CurrentDomain.BaseDirectory}\\AppData\\{questionNum}\\";

            if (!Directory.Exists(root))
            {
                Directory.CreateDirectory(root);
            }

            for (int i = 0; i < imgs.Count; i++)
            {
                var full = root + (t + i + 1) + ".png";
                SavePhotoFromUrl(full, imgs[i]);
                Console.WriteLine(full);
            }
        }


        private static void SavePhotoFromUrl(string fullName, string url)
        {
            var response = default(WebResponse);
            var stream = default(Stream);
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                response = request.GetResponse();
                stream = response.GetResponseStream();

                using (Bitmap image = new Bitmap(stream))
                {
                    image.Save(fullName);
                }
            }
            catch (InvalidOperationException)
            {
                Console.WriteLine($"未找到{url}");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        /// <summary>
        /// 使用C#动态特性拿取头像url
        /// </summary>
        /// <param name="j"></param>
        /// <returns></returns>
        private static List<string> GetImgStr(string j)
        {
            var list = new List<string>();
            var obj = JsonConvert.DeserializeObject<dynamic>(j);
            foreach (var item in obj.data)
            {
                list.Add(item.author.avatar_url_template.Value);
            }
            return list;
        }


        private static bool HtmlPreRequest(HttpWebRequest request)
        {
            request.AllowAutoRedirect = true;
            request.KeepAlive = true;
            request.Method = "GET";
            // 随机UserAgent
            request.UserAgent = FakeUserAgent.Ramdom;
            return true;
        }

        /// <summary>
        /// 知乎获取问题列表api
        /// </summary>
        /// <param name="qNum">问题编号</param>
        /// <param name="offset">偏移量</param>
        /// <param name="limit">读取最大行数</param>
        /// <returns></returns>
        private static string GetUrl(string qNum, decimal offset, decimal limit = 20)
        {
            return $"https://www.zhihu.com/api/v4/questions/{qNum}/answers?limit={limit}&offset={offset}&platform=desktop&sort_by=default";
        }

        private static string Http(string url, string method = "GET", string contenttype = "application/json;charset=utf-8", Hashtable header = null, string data = null)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = string.IsNullOrEmpty(method) ? "GET" : method;
            request.ContentType = string.IsNullOrEmpty(contenttype) ? "application/json;charset=utf-8" : contenttype;
            request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36";
            if (header != null)
            {
                foreach (var i in header.Keys)
                {
                    request.Headers.Add(i.ToString(), header[i].ToString());
                }
            }
            if (!string.IsNullOrEmpty(data))
            {
                using (Stream RequestStream = request.GetRequestStream())
                {
                    byte[] bytes = Encoding.UTF8.GetBytes(data);
                    RequestStream.Write(bytes, 0, bytes.Length);
                }
            }

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            using (Stream ResponseStream = response.GetResponseStream())
            {
                using (StreamReader StreamReader = new StreamReader(ResponseStream, Encoding.GetEncoding("utf-8")))
                {
                    string re = StreamReader.ReadToEnd();
                    return re;
                }
            }
        }


    }
}
